package com.zsk.shop.service;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zsk.shop.common.utils.ToolUtil;
import com.zsk.shop.entity.UserLogInfo;
import com.zsk.shop.enums.EnumLoginPlatform;
import com.zsk.shop.enums.EnumUserLogType;
import com.zsk.shop.mapper.UserLoginInfoMapper;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

@Service
@DS("master")
public class UserLogInfoService extends ServiceImpl<UserLoginInfoMapper, UserLogInfo> {

    /**
     * @param userNo
     * @param platform    {@link EnumLoginPlatform}
     * @param deviceToken
     * @param type        {@link EnumUserLogType}
     */
    public void insertInfo(String userNo, String platform, String deviceToken, Integer type) {
        UserLogInfo userLogInfo = new UserLogInfo();
        userLogInfo.setType(type);
        userLogInfo.setUserNo(userNo);
        userLogInfo.setUserType(0);
        userLogInfo.setPlatform(ToolUtil.isNotEmpty(platform) ? platform : EnumLoginPlatform.NULL.getName());
        userLogInfo.setDeviceToken(ToolUtil.isNotEmpty(deviceToken) ? deviceToken : "");
        userLogInfo.setLogTime(new Date());
        this.save(userLogInfo);
    }

    public UserLogInfo queryLastLoginByUserNo(String userNo) {
        if (ToolUtil.isEmpty(userNo)) {
            return new UserLogInfo();
        }
        LambdaQueryWrapper<UserLogInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserLogInfo::getUserNo, userNo);
        queryWrapper.orderByDesc(UserLogInfo::getLogTime);
        queryWrapper.last("limit 1");
        return this.getOne(queryWrapper);
    }

    //查询登录相关的内容
    public List<UserLogInfo> queryLoginByUserNos(List<String> userNos, Boolean isFirstNotLast) {
        if (ToolUtil.isEmpty(userNos)) {
            return new ArrayList<>();
        }
        LambdaQueryWrapper<UserLogInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserLogInfo::getType, EnumUserLogType.LOGIN.getCode());
        queryWrapper.in(UserLogInfo::getUserNo, userNos);
        if (isFirstNotLast) {
            queryWrapper.orderByAsc(UserLogInfo::getLogTime);
        } else {
            queryWrapper.orderByDesc(UserLogInfo::getLogTime);
        }
        List<UserLogInfo> list = this.list(queryWrapper);
        List<UserLogInfo> result = list.stream().filter(distinctByKey(UserLogInfo::getUserNo)).collect(Collectors.toList());
        return result;
    }

    private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        Set<Object> seen = ConcurrentHashMap.newKeySet();
        return t -> seen.add(keyExtractor.apply(t));
    }


}
